package app.error.handler;

import com.dj.common.exception.ApiBusinessException;
import com.dj.common.exception.SystemException;
import com.dj.gateway.app.error.GatewayError;
import com.dj.gateway.app.error.GatewayErrorType;
import com.dj.gateway.app.exception.GatewayUnauthorizedException;
import io.netty.channel.ConnectTimeoutException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;

@Slf4j
@Component
public class GatewayHandlerExceptionAdvice  {

    public GatewayError handleResponseStatusException(ResponseStatusException ex) {
        log.error("response status exception", ex);
        return GatewayError.fail(GatewayErrorType.SYSTEM_ERROR);
    }

    public GatewayError handleConnectTimeoutException(ConnectTimeoutException ex) {
        log.error("connect timeout exception", ex);
        return GatewayError.fail(GatewayErrorType.GATEWAY_CONNECT_TIME_OUT);
    }

    public GatewayError handleNotFoundException(NotFoundException ex) {
        log.error("not found exception", ex);
        return GatewayError.fail(GatewayErrorType.GATEWAY_NOT_FOUND_SERVICE);
    }

    public GatewayError handleApiBusinessException(ApiBusinessException ex) {
        log.error("ApiBusinessException", ex);
        return GatewayError.fail(ex.getCode(), ex.getMessage());
    }

    public GatewayError handleGatewayUnauthorizedException(GatewayUnauthorizedException ex) {
        log.error("GatewayUnauthorizedException", ex);
        return GatewayError.fail(GatewayErrorType.UNAUTHORIZED);
    }

    public GatewayError handleSystemException(SystemException ex) {
        log.error("SystemException", ex);
        return GatewayError.fail(GatewayErrorType.SYSTEM_ERROR);
    }

    public GatewayError handleRuntimeException(RuntimeException ex) {
        log.error("runtime exception", ex);
        return GatewayError.fail(GatewayErrorType.SYSTEM_ERROR);
    }

    public GatewayError handleException(Exception ex) {
        log.error("exception", ex);
        return GatewayError.fail(GatewayErrorType.SYSTEM_ERROR);
    }

    public GatewayError handle(Throwable throwable) {
        GatewayError result = null;
        if (throwable instanceof NotFoundException) {
            result = handleNotFoundException((NotFoundException) throwable);
        } else if (throwable instanceof ResponseStatusException) {
            result = handleResponseStatusException((ResponseStatusException) throwable);
        } else if (throwable instanceof ConnectTimeoutException) {
            result = handleConnectTimeoutException((ConnectTimeoutException) throwable);
        } else if (throwable instanceof ApiBusinessException) {
            result = handleApiBusinessException((ApiBusinessException) throwable);
        } else if (throwable instanceof GatewayUnauthorizedException) {
            result = handleGatewayUnauthorizedException((GatewayUnauthorizedException) throwable);
        } else if (throwable instanceof SystemException) {
            result = handleSystemException((SystemException) throwable);
        } else if (throwable instanceof RuntimeException) {
            result = handleRuntimeException((RuntimeException) throwable);
        } else if (throwable instanceof Exception) {
            result = handleException((Exception) throwable);
        } else {
        	result = GatewayError.fail(GatewayErrorType.SYSTEM_ERROR);
        }
        return result;
    }

}
